home *** CD-ROM | disk | FTP | other *** search
/ Acorn RISC PD-CD 1 / Acorn RISC PD-CD 1.iso / utilities / _graphics / graphics / _jpeg / c / jwrjfif < prev    next >
Encoding:
Text File  |  1991-10-28  |  11.4 KB  |  469 lines

  1. /*
  2.  * jwrjfif.c
  3.  *
  4.  * Copyright (C) 1991, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains routines to write standard JPEG file headers/markers.
  9.  * The file format created is a raw JPEG data stream with (optionally) an
  10.  * APP0 marker per the JFIF spec.  This will handle baseline and
  11.  * JFIF-convention JPEG files, although there is currently no provision
  12.  * for inserting a thumbnail image in the JFIF header.
  13.  *
  14.  * These routines may need modification for non-Unix environments or
  15.  * specialized applications.  As they stand, they assume output to
  16.  * an ordinary stdio stream.  However, the changes to write to something
  17.  * else are localized in the macros appearing just below.
  18.  *
  19.  * These routines are invoked via the methods write_file_header,
  20.  * write_scan_header, write_jpeg_data, write_scan_trailer, and
  21.  * write_file_trailer.
  22.  */
  23.  
  24. #include "jinclude.h"
  25.  
  26. #ifdef JFIF_SUPPORTED
  27.  
  28.  
  29. /*
  30.  * To output to something other than a stdio stream, you'd need to redefine
  31.  * these macros.
  32.  */
  33.  
  34. /* Write a single byte */
  35. #define emit_byte(cinfo,x)  putc((x), cinfo->output_file)
  36.  
  37. /* Write some bytes from a (char *) buffer */
  38. #define WRITE_BYTES(cinfo,dataptr,datacount)  \
  39.   { if (fwrite((dataptr), 1, (datacount), cinfo->output_file) != (datacount)) \
  40.       ERREXIT(cinfo->emethods, "Output file write error"); }
  41.  
  42. /* Clean up and verify successful output */
  43. #define CHECK_OUTPUT(cinfo)  \
  44.   { fflush(cinfo->output_file); \
  45.     if (ferror(cinfo->output_file)) \
  46.       ERREXIT(cinfo->emethods, "Output file write error"); }
  47.  
  48.  
  49. /* End of stdio-specific code. */
  50.  
  51.  
  52. typedef enum {                  /* JPEG marker codes */
  53.   M_SOF0  = 0xc0,
  54.   M_SOF1  = 0xc1,
  55.   M_SOF2  = 0xc2,
  56.   M_SOF3  = 0xc3,
  57.   
  58.   M_SOF5  = 0xc5,
  59.   M_SOF6  = 0xc6,
  60.   M_SOF7  = 0xc7,
  61.   
  62.   M_JPG   = 0xc8,
  63.   M_SOF9  = 0xc9,
  64.   M_SOF10 = 0xca,
  65.   M_SOF11 = 0xcb,
  66.   
  67.   M_SOF13 = 0xcd,
  68.   M_SOF14 = 0xce,
  69.   M_SOF15 = 0xcf,
  70.   
  71.   M_DHT   = 0xc4,
  72.   
  73.   M_DAC   = 0xcc,
  74.   
  75.   M_RST0  = 0xd0,
  76.   M_RST1  = 0xd1,
  77.   M_RST2  = 0xd2,
  78.   M_RST3  = 0xd3,
  79.   M_RST4  = 0xd4,
  80.   M_RST5  = 0xd5,
  81.   M_RST6  = 0xd6,
  82.   M_RST7  = 0xd7,
  83.   
  84.   M_SOI   = 0xd8,
  85.   M_EOI   = 0xd9,
  86.   M_SOS   = 0xda,
  87.   M_DQT   = 0xdb,
  88.   M_DNL   = 0xdc,
  89.   M_DRI   = 0xdd,
  90.   M_DHP   = 0xde,
  91.   M_EXP   = 0xdf,
  92.   
  93.   M_APP0  = 0xe0,
  94.   M_APP15 = 0xef,
  95.   
  96.   M_JPG0  = 0xf0,
  97.   M_JPG13 = 0xfd,
  98.   M_COM   = 0xfe,
  99.   
  100.   M_TEM   = 0x01,
  101.   
  102.   M_ERROR = 0x100
  103. } JPEG_MARKER;
  104.  
  105.  
  106. LOCAL void
  107. emit_marker (compress_info_ptr cinfo, JPEG_MARKER mark)
  108. /* Emit a marker code */
  109. {
  110.   emit_byte(cinfo, 0xFF);
  111.   emit_byte(cinfo, mark);
  112. }
  113.  
  114.  
  115. LOCAL void
  116. emit_2bytes (compress_info_ptr cinfo, int value)
  117. /* Emit a 2-byte integer; these are always MSB first in JPEG files */
  118. {
  119.   emit_byte(cinfo, (value >> 8) & 0xFF);
  120.   emit_byte(cinfo, value & 0xFF);
  121. }
  122.  
  123.  
  124. LOCAL int
  125. emit_dqt (compress_info_ptr cinfo, int index)
  126. /* Emit a DQT marker */
  127. /* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
  128. {
  129.   QUANT_TBL_PTR data = cinfo->quant_tbl_ptrs[index];
  130.   int prec = 0;
  131.   int i;
  132.   
  133.   for (i = 0; i < DCTSIZE2; i++) {
  134.     if (data[i] > 255)
  135.       prec = 1;
  136.   }
  137.  
  138.   emit_marker(cinfo, M_DQT);
  139.   
  140.   emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
  141.   
  142.   emit_byte(cinfo, index + (prec<<4));
  143.   
  144.   for (i = 0; i < DCTSIZE2; i++) {
  145.     if (prec)
  146.       emit_byte(cinfo, data[i] >> 8);
  147.     emit_byte(cinfo, data[i] & 0xFF);
  148.   }
  149.  
  150.   return prec;
  151. }
  152.  
  153.  
  154. LOCAL void
  155. emit_dht (compress_info_ptr cinfo, int index, boolean is_ac)
  156. /* Emit a DHT marker */
  157. {
  158.   HUFF_TBL * htbl;
  159.   int length, i;
  160.   
  161.   if (is_ac) {
  162.     htbl = cinfo->ac_huff_tbl_ptrs[index];
  163.     index += 0x10;              /* output index has AC bit set */
  164.   } else {
  165.     htbl = cinfo->dc_huff_tbl_ptrs[index];
  166.   }
  167.   
  168.   if (! htbl->sent_table) {
  169.     emit_marker(cinfo, M_DHT);
  170.     
  171.     length = 0;
  172.     for (i = 1; i <= 16; i++)
  173.       length += htbl->bits[i];
  174.     
  175.     emit_2bytes(cinfo, length + 2 + 1 + 16);
  176.     emit_byte(cinfo, index);
  177.     
  178.     for (i = 1; i <= 16; i++)
  179.       emit_byte(cinfo, htbl->bits[i]);
  180.     
  181.     for (i = 0; i < length; i++)
  182.       emit_byte(cinfo, htbl->huffval[i]);
  183.     
  184.     htbl->sent_table = TRUE;
  185.   }
  186. }
  187.  
  188.  
  189. LOCAL void
  190. emit_dac (compress_info_ptr cinfo)
  191. /* Emit a DAC marker */
  192. /* Since the useful info is so small, we want to emit all the tables in */
  193. /* one DAC marker.  Therefore this routine does its own scan of the table. */
  194. {
  195.   char dc_in_use[NUM_ARITH_TBLS];
  196.   char ac_in_use[NUM_ARITH_TBLS];
  197.   int length, i;
  198.   
  199.   for (i = 0; i < NUM_ARITH_TBLS; i++)
  200.     dc_in_use[i] = ac_in_use[i] = 0;
  201.   
  202.   for (i = 0; i < cinfo->num_components; i++) {
  203.     dc_in_use[cinfo->comp_info[i].dc_tbl_no] = 1;
  204.     ac_in_use[cinfo->comp_info[i].ac_tbl_no] = 1;
  205.   }
  206.   
  207.   length = 0;
  208.   for (i = 0; i < NUM_ARITH_TBLS; i++)
  209.     length += dc_in_use[i] + ac_in_use[i];
  210.   
  211.   emit_marker(cinfo, M_DAC);
  212.   
  213.   emit_2bytes(cinfo, length*2 + 2);
  214.   
  215.   for (i = 0; i < NUM_ARITH_TBLS; i++) {
  216.     if (dc_in_use[i]) {
  217.       emit_byte(cinfo, i);
  218.       emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
  219.     }
  220.     if (ac_in_use[i]) {
  221.       emit_byte(cinfo, i + 0x10);
  222.       emit_byte(cinfo, cinfo->arith_ac_K[i]);
  223.     }
  224.   }
  225. }
  226.  
  227.  
  228. LOCAL void
  229. emit_dri (compress_info_ptr cinfo)
  230. /* Emit a DRI marker */
  231. {
  232.   emit_marker(cinfo, M_DRI);
  233.   
  234.   emit_2bytes(cinfo, 4);        /* fixed length */
  235.  
  236.   emit_2bytes(cinfo, (int) cinfo->restart_interval);
  237. }
  238.  
  239.  
  240. LOCAL void
  241. emit_sof (compress_info_ptr cinfo, JPEG_MARKER code)
  242. /* Emit a SOF marker */
  243. {
  244.   int i;
  245.   
  246.   emit_marker(cinfo, code);
  247.   
  248.   emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
  249.  
  250.   emit_byte(cinfo, cinfo->data_precision);
  251.   emit_2bytes(cinfo, (int) cinfo->image_height);
  252.   emit_2bytes(cinfo, (int) cinfo->image_width);
  253.  
  254.   emit_byte(cinfo, cinfo->num_components);
  255.  
  256.   for (i = 0; i < cinfo->num_components; i++) {
  257.     emit_byte(cinfo, cinfo->comp_info[i].component_id);
  258.     emit_byte(cinfo, (cinfo->comp_info[i].h_samp_factor << 4)
  259.                      + cinfo->comp_info[i].v_samp_factor);
  260.     emit_byte(cinfo, cinfo->comp_info[i].quant_tbl_no);
  261.   }
  262. }
  263.  
  264.  
  265. LOCAL void
  266. emit_sos (compress_info_ptr cinfo)
  267. /* Emit a SOS marker */
  268. {
  269.   int i;
  270.   
  271.   emit_marker(cinfo, M_SOS);
  272.   
  273.   emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
  274.   
  275.   emit_byte(cinfo, cinfo->comps_in_scan);
  276.   
  277.   for (i = 0; i < cinfo->comps_in_scan; i++) {
  278.     emit_byte(cinfo, cinfo->cur_comp_info[i]->component_id);
  279.     emit_byte(cinfo, (cinfo->cur_comp_info[i]->dc_tbl_no << 4)
  280.                      + cinfo->cur_comp_info[i]->ac_tbl_no);
  281.   }
  282.  
  283.   emit_byte(cinfo, 0);          /* Spectral selection start */
  284.   emit_byte(cinfo, DCTSIZE2-1); /* Spectral selection end */
  285.   emit_byte(cinfo, 0);          /* Successive approximation */
  286. }
  287.  
  288.  
  289. LOCAL void
  290. emit_jfif_app0 (compress_info_ptr cinfo)
  291. /* Emit a JFIF-compliant APP0 marker */
  292. {
  293.   /*
  294.    * Length of APP0 block       (2 bytes)
  295.    * Block ID                   (4 bytes - ASCII "JFIF")
  296.    * Zero byte                  (1 byte to terminate the ID string)
  297.    * Version Major, Minor       (2 bytes - 0x01, 0x01)
  298.    * Units                      (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
  299.    * Xdpu                       (2 bytes - dots per unit horizontal)
  300.    * Ydpu                       (2 bytes - dots per unit vertical)
  301.    * Thumbnail X size           (1 byte)
  302.    * Thumbnail Y size           (1 byte)
  303.    */
  304.   
  305.   emit_marker(cinfo, M_APP0);
  306.   
  307.   emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */
  308.  
  309.   emit_byte(cinfo, 'J');        /* Identifier */
  310.   emit_byte(cinfo, 'F');
  311.   emit_byte(cinfo, 'I');
  312.   emit_byte(cinfo, 'F');
  313.   emit_byte(cinfo, 0);
  314.   emit_byte(cinfo, 1);          /* Major version */
  315.   emit_byte(cinfo, 1);          /* Minor version */
  316.   emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
  317.   emit_2bytes(cinfo, (int) cinfo->X_density);
  318.   emit_2bytes(cinfo, (int) cinfo->Y_density);
  319.   emit_byte(cinfo, 0);          /* No thumbnail image */
  320.   emit_byte(cinfo, 0);
  321. }
  322.  
  323.  
  324. /*
  325.  * Write the file header.
  326.  */
  327.  
  328.  
  329. METHODDEF void
  330. write_file_header (compress_info_ptr cinfo)
  331. {
  332.   char qt_in_use[NUM_QUANT_TBLS];
  333.   int i, prec;
  334.   boolean is_baseline;
  335.   
  336.   emit_marker(cinfo, M_SOI);    /* first the SOI */
  337.  
  338.   if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */
  339.     emit_jfif_app0(cinfo);
  340.  
  341.   /* Emit DQT for each quantization table. */
  342.   /* Note that doing it here means we can't adjust the QTs on-the-fly. */
  343.   /* If we did want to do that, we'd have a problem with checking precision */
  344.   /* for the is_baseline determination. */
  345.  
  346.   for (i = 0; i < NUM_QUANT_TBLS; i++)
  347.     qt_in_use[i] = 0;
  348.  
  349.   for (i = 0; i < cinfo->num_components; i++)
  350.     qt_in_use[cinfo->comp_info[i].quant_tbl_no] = 1;
  351.  
  352.   prec = 0;
  353.   for (i = 0; i < NUM_QUANT_TBLS; i++) {
  354.     if (qt_in_use[i])
  355.       prec += emit_dqt(cinfo, i);
  356.   }
  357.   /* now prec is nonzero iff there are any 16-bit quant tables. */
  358.  
  359.   if (cinfo->restart_interval)
  360.     emit_dri(cinfo);
  361.  
  362.   /* Check for a non-baseline specification. */
  363.   /* Note we assume that Huffman table numbers won't be changed later. */
  364.   is_baseline = TRUE;
  365.   if (cinfo->arith_code || (cinfo->data_precision != 8))
  366.     is_baseline = FALSE;
  367.   for (i = 0; i < cinfo->num_components; i++) {
  368.     if (cinfo->comp_info[i].dc_tbl_no > 1 || cinfo->comp_info[i].ac_tbl_no > 1)
  369.       is_baseline = FALSE;
  370.   }
  371.   if (prec && is_baseline) {
  372.     is_baseline = FALSE;
  373.     /* If it's baseline except for quantizer size, warn the user */
  374.     TRACEMS(cinfo->emethods, 0,
  375.             "Caution: quantization tables are too coarse for baseline JPEG");
  376.   }
  377.  
  378.  
  379.   /* Emit the proper SOF marker */
  380.   if (cinfo->arith_code)
  381.     emit_sof(cinfo, M_SOF9);    /* SOF code for arithmetic coding */
  382.   else if (is_baseline)
  383.     emit_sof(cinfo, M_SOF0);    /* SOF code for baseline implementation */
  384.   else
  385.     emit_sof(cinfo, M_SOF1);    /* SOF code for non-baseline Huffman file */
  386. }
  387.  
  388.  
  389. /*
  390.  * Write the start of a scan (everything through the SOS marker).
  391.  */
  392.  
  393. METHODDEF void
  394. write_scan_header (compress_info_ptr cinfo)
  395. {
  396.   int i;
  397.  
  398.   if (cinfo->arith_code) {
  399.     /* Emit arith conditioning info.  We will have some duplication
  400.      * if the file has multiple scans, but it's so small it's hardly
  401.      * worth worrying about.
  402.      */
  403.     emit_dac(cinfo);
  404.   } else {
  405.     /* Emit Huffman tables.  Note that emit_dht takes care of
  406.      * suppressing duplicate tables.
  407.      */
  408.     for (i = 0; i < cinfo->comps_in_scan; i++) {
  409.       emit_dht(cinfo, cinfo->cur_comp_info[i]->dc_tbl_no, FALSE);
  410.       emit_dht(cinfo, cinfo->cur_comp_info[i]->ac_tbl_no, TRUE);
  411.     }
  412.   }
  413.  
  414.   emit_sos(cinfo);
  415. }
  416.  
  417.  
  418. /*
  419.  * Write some bytes of compressed data within a scan.
  420.  */
  421.  
  422. METHODDEF void
  423. write_jpeg_data (compress_info_ptr cinfo, char *dataptr, int datacount)
  424. {
  425.   WRITE_BYTES(cinfo, dataptr, datacount);
  426. }
  427.  
  428.  
  429. /*
  430.  * Finish up after a compressed scan (series of write_jpeg_data calls).
  431.  */
  432.  
  433. METHODDEF void
  434. write_scan_trailer (compress_info_ptr cinfo)
  435. {
  436.   /* no work needed in this format */
  437. }
  438.  
  439.  
  440. /*
  441.  * Finish up at the end of the file.
  442.  */
  443.  
  444. METHODDEF void
  445. write_file_trailer (compress_info_ptr cinfo)
  446. {
  447.   emit_marker(cinfo, M_EOI);
  448.   /* Make sure we wrote the output file OK */
  449.   CHECK_OUTPUT(cinfo);
  450. }
  451.  
  452.  
  453. /*
  454.  * The method selection routine for standard JPEG header writing.
  455.  * This should be called from c_ui_method_selection if appropriate.
  456.  */
  457.  
  458. GLOBAL void
  459. jselwjfif (compress_info_ptr cinfo)
  460. {
  461.   cinfo->methods->write_file_header = write_file_header;
  462.   cinfo->methods->write_scan_header = write_scan_header;
  463.   cinfo->methods->write_jpeg_data = write_jpeg_data;
  464.   cinfo->methods->write_scan_trailer = write_scan_trailer;
  465.   cinfo->methods->write_file_trailer = write_file_trailer;
  466. }
  467.  
  468. #endif /* JFIF_SUPPORTED */
  469.